package com.hc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hc.common.service.RedisService;
import com.hc.constant.RedisConst;
import com.hc.domain.Country;
import com.hc.mapper.CountryMapper;
import com.hc.service.CountryService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author hecai
 */
@Service
@CacheConfig(cacheManager = "cacheManager")
public class CountryServiceImpl extends ServiceImpl<CountryMapper, Country> implements CountryService {

    @Resource
    private RedisService<Country> countryRedisService;

    @Resource
    private RedisService<List<Country>> cityCountryRedisService;

    @Override
    @CachePut(value = RedisConst.COUNTRY, key = "#country.id", condition = "#flag==true")
    public Country insertCountry(Country country, Boolean flag) {
        //插入Country信息到数据库，同时会更新单独的Country信息
        int insertRes = baseMapper.insert(country);
        if (insertRes == 1) {
            //获取缓存中的Country列表
            List<Country> countryList = cityCountryRedisService.get(RedisConst.CITY_COUNTRY + "::" + country.getCityId());
            countryList.add(country);
            //排序
            countryList.sort((item1, item2) -> {
                int t1 = item1.getPriority() == null ? 0 : item1.getPriority();
                int t2 = item2.getPriority() == null ? 0 : item2.getPriority();
                return t2 - t1;
            });
            //将更新后的Country列表信息保存到Redis
            cityCountryRedisService.set(RedisConst.CITY_COUNTRY + "::" + country.getCityId(), countryList);
        }
        return country;
    }

    @Override
    @Cacheable(value = RedisConst.COUNTRY, key = "#id", condition = "#flag==true", unless = "#result==null")
    public Country findCountryById(Integer id, Boolean flag) {
        //查询，先从Redis中查：如果Redis中有直接返回，如果Redis中没有则从数据库中查，查到之后将数据缓存到Redis中
        Country country = baseMapper.selectById(id);
        return country;
    }

    @Override
    @Cacheable(value = RedisConst.CITY_COUNTRY, key = "#cityId", condition = "#flag==true", unless = "#result.size()==0")
    public List<Country> findCountryByCityId(Integer cityId, Boolean flag) {
        QueryWrapper<Country> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("city_id", cityId);
        List<Country> countryList = baseMapper.selectList(queryWrapper);
        return countryList;
    }

    @Override
    @CachePut(value = RedisConst.COUNTRY, key = "#country.id", condition = "#flag==true")
    public Country updateCountry(Country country, Boolean flag) {
        //原City
        Country country0 = countryRedisService.get(RedisConst.COUNTRY + "::" + country.getId());

        int updateRes = baseMapper.updateById(country);
        //更新后的完整的City
        country = baseMapper.selectById(country.getId());

        if (updateRes == 1) {
            //目标省下的所有City
            List<Country> countryList = cityCountryRedisService.get(RedisConst.CITY_COUNTRY + "::" + country.getCityId());

            //如果原city在目标城市中，即没有换城市
            boolean flag2 = true;
            for (int i = 0; i < countryList.size(); i++) {
                Country item = countryList.get(i);
                if (item.getId().equals(country0.getId())) {
                    countryList.set(i, country);
                    flag2 = false;
                    break;
                }
            }
            //排序
            countryList.sort((item1, item2) -> {
                int t1 = item1.getPriority() == null ? 0 : item1.getPriority();
                int t2 = item2.getPriority() == null ? 0 : item2.getPriority();
                return t2 - t1;
            });
            cityCountryRedisService.set(RedisConst.CITY_COUNTRY + "::" + country.getCityId(), countryList);

            //换城市了
            if (flag2) {
                //原来的城市下的country列表减去
                List<Country> cityList0 = cityCountryRedisService.get(RedisConst.CITY_COUNTRY + "::" + country0.getCityId());
                for (int i = 0; i < cityList0.size(); i++) {
                    if (cityList0.get(i).getId().equals(country0.getId())) {
                        cityList0.remove(i);
                        break;
                    }
                }
                cityCountryRedisService.set(RedisConst.CITY_COUNTRY + "::" + country0.getCityId(), cityList0);

                //目标城市下的country列表增加
                countryList.add(country);
                //排序
                countryList.sort((item1, item2) -> {
                    int t1 = item1.getPriority() == null ? 0 : item1.getPriority();
                    int t2 = item2.getPriority() == null ? 0 : item2.getPriority();
                    return t2 - t1;
                });
                cityCountryRedisService.set(RedisConst.CITY_COUNTRY + "::" + country.getCityId(), countryList);
            }
        }
        return country;
    }

    @Override
    @CacheEvict(value = RedisConst.COUNTRY, key = "#id", condition = "#flag==true")
    public Country deleteCountryById(Integer id, Boolean flag) {
        Country country = countryRedisService.get(RedisConst.COUNTRY + "::" + id);
        if (country != null) {
            List<Country> countryList = cityCountryRedisService.get(RedisConst.CITY_COUNTRY + "::" + country.getCityId());
            for (int i = 0; i < countryList.size(); i++) {
                Country item = countryList.get(i);
                if (item.getId().equals(id)) {
                    countryList.remove(i);
                    break;
                }
            }
            cityCountryRedisService.set(RedisConst.CITY_COUNTRY + "::" + country.getCityId(), countryList);
            baseMapper.deleteById(id);
        }
        return country;
    }

    @Override
    public String selectProvinceCityCountryByCountryId(Integer countryId) {
        return baseMapper.selectProvinceCityCountryByCountryId(countryId);
    }
}
